import io
import re

import numpy as np
from minio import Minio
from loguru import logger

from app.schemas.storage import OssConfig

def oss_upload(oss_config: OssConfig):
    handler = None
    pattern = r"(http|https):\/\/(.*)"
    match = re.search(pattern, oss_config.endpoint)
    endpoint = match.group(2)
    handler = Minio(
        endpoint=endpoint,
        access_key=oss_config.access_key,
        secret_key=oss_config.secret_key,
        secure=False,
        session_token=oss_config.security_token
    )

    def minio_upload(file_name: str, file_data: bytes | bytes, img_quality=95):
        _handler: Minio = handler
        object_key = oss_config.object_key_prefix + '/' + file_name
        content_type = get_mime_type(file_name)

        bits_len = len(file_data)
        io_bytes = io.BytesIO(file_data)

        _handler.put_object(
            bucket_name=oss_config.bucket,
            object_name=object_key,
            data=io_bytes,
            length=bits_len,
            content_type=content_type
        )
        io_bytes.close()

        return object_key

    def inner(file_name: str, img_data: np.ndarray | bytes, img_quality=95):
        _upload = minio_upload
        res = None
        try:
            res = _upload(file_name, img_data, img_quality)
        except:
            logger.exception('【oss-upload】上传图像失败')
        finally:
            return res

    return inner


def get_mime_type(file_name: str) -> str:
    """根据文件名获取MIME类型

    Parameters
    ----------
    file_name : str
        文件名，包含扩展名

    Returns
    -------
    str
        MIME类型
    """
    if '.' in file_name:
        suffix = file_name.rsplit('.', 1)[1].lower()
    else:
        suffix = ''

    mime_types = {
        'pdf': 'application/pdf',
        'json': 'application/json',
        'jpg': 'image/jpeg',
        'jpeg': 'image/jpeg',
        'png': 'image/png',
        'svg': 'image/svg+xml',
        'mp4': 'video/mp4'
    }
    return mime_types.get(suffix, 'application/octet-stream')